import Snake from './Snake';
import Food from './Food';
import ScorePanel from './ScorePanel';
import GameInfo from './GameInfo';

class GameControl {

    snake : Snake;
    food : Food;
    scorePanel : ScorePanel;
    gameinfo : GameInfo;

    start : boolean = false;
    gameOver :boolean = true;

    constructor(){
        this.gameinfo = new GameInfo();
        this.snake = new Snake(this.gameinfo);
        this.food = new Food();
        this.scorePanel = new ScorePanel(this.onLevelUp.bind(this), this.gameinfo, 20);

        this.food.change();

        this.init();
    }

    // 初始化游戏
    init(){
        let eventTimestamp = 0;

        document.addEventListener('keydown', (keyEvent:KeyboardEvent)=>{
            if(!this.start || keyEvent.timeStamp-eventTimestamp<200){  // 规定键盘至多每 100 毫秒响应一次事件
                return;
            }
            eventTimestamp = keyEvent.timeStamp;
            const key = keyEvent.key;
            if(key==='w' || key.includes('Up')){
                this.snake.turnUp(this.gameOverHandle.bind(this), this.eatFood.bind(this));
            } else if(key==='s' || key.includes('Down')){
                this.snake.turnDown(this.gameOverHandle.bind(this), this.eatFood.bind(this));
            }  else if(key==='a' || key.includes('Left')){
                this.snake.turnLeft(this.gameOverHandle.bind(this), this.eatFood.bind(this));
            }  else if(key==='d' || key.includes('Right')){
                this.snake.turnRight(this.gameOverHandle.bind(this), this.eatFood.bind(this));
            } 
            
        });

        this.gameinfo.buttonClick((evt)=>{
            console.log(evt);
            if(this.gameOver){
                this.gameOver = false;
                this.start = true;
                this.gameinfo.appendLog('游戏重新开始');
                (evt!.target as HTMLElement).innerText = ' 暂 停 ';
                this.scorePanel.reset();
                this.snake.reSet();
                this.randomFood();
                this.onLevelUp();
                this.run();
            } else if(this.start){
                this.start = false;
                this.gameinfo.appendLog('游戏暂停');
                (evt!.target as HTMLElement).innerText = ' 恢 复 ';
            } else {
                this.start = true;
                this.gameinfo.appendLog('游戏开始');
                (evt!.target as HTMLElement).innerText = ' 暂 停 ';
                this.run();
            }
        });

        this.onLevelUp();
        this.run();
    }

    /**
     * 让贪吃蛇定时移动，并判定是否吃到食物，在吃到食物后重新随机食物的位置
     */
    run(){
        if(this.start){
            this.snake.move(this.gameOverHandle.bind(this));
            this.eatFood();
            setTimeout(this.run.bind(this), this.getGameDuration());
        }
    }

    getGameDuration(){
        return 200 - (this.scorePanel.level - 1)*15;
    }
    
    onLevelUp(){
        this.snake.snake.parentElement!.style.transitionDuration = this.getGameDuration() + 'ms';
    }

    /**
     * 判定是否吃到食物，在吃到食物后重新随机食物的位置
     */
    eatFood(){
        if(this.snake.X===this.food.X && this.snake.Y===this.food.Y){
            this.gameinfo.appendLog('吃到食物了...');
            this.randomFood();
            this.scorePanel.addScore();
            this.snake.addBody();
        }
    }

    randomFood(){
        this.food.change();
        if(this.snake.checkBody(this.food.X, this.food.Y)){
            this.randomFood();
        }
    }

    gameOverHandle(reason:string){
        if(this.start){
            this.start=false;
            setTimeout(()=>{
                this.gameinfo.appendLog(`${reason},游戏结束！！`);
                this.gameinfo.reSet();
                this.gameOver = true;
            }, this.getGameDuration());
        }
    }

}


export default GameControl;